/**
 * 根据最后位置计算 page 滚动到顶部的值。
 *
 * 也可计算水平方向的滚动值。
 *
 *                      page
 *                     ╱
 *    ╭───────────────╮    viewport
 *  ╭─│─ ─ ─ ─ ─ ─ ─ ─│─╮ ╱
 *  │ │ ╭───────────╮ │ │
 *  │ │ │  element  │ │ │
 *  │ │ ╰───────────╯ │ │
 *  ╰─│─ ─ ─ ─ ─ ─ ─ ─│─╯
 *    │               │
 *    │               │
 *    ╰───────────────╯
 *
 * @param {number} viewportHeight viewport 高度
 * @param {number} viewportScrollTop viewport 垂直滚动值
 * @param {number} elementHeight element 高度
 * @param {number} elementOffsetTop element 距离页面顶部距离
 * @param {string} options.position element 在 viewport 中的位置，可选：'start' | 'center' | 'end' | 'nearest'
 * @param {number} options.startOffset element 距离视窗顶部的偏移量
 * @param {number} options.endOffset element 距离视窗底部的偏移量
 * @return {number} viewport 新的垂直滚动值
 */
export function getScrollIntoViewValue(viewportHeight, viewportScrollTop, elementHeight, elementOffsetTop, options = {}) {
    const { startOffset = 0, endOffset = 0 } = options;
    let position = options.position || 'nearest';
    const elementToViewportTopOffset = elementOffsetTop - viewportScrollTop - startOffset;
    const elementToViewportBottomOffset = elementOffsetTop +
        elementHeight -
        viewportScrollTop -
        viewportHeight +
        endOffset;
    if (position === 'nearest') {
        if (elementToViewportTopOffset >= 0 && elementToViewportBottomOffset <= 0) {
            return viewportScrollTop;
        }
        else {
            position =
                Math.abs(elementToViewportTopOffset) >
                    Math.abs(elementToViewportBottomOffset)
                    ? 'end'
                    : 'start';
        }
    }
    let nextScrollTop = 0;
    switch (position) {
        case 'start':
            nextScrollTop = elementOffsetTop - startOffset;
            break;
        case 'center':
            nextScrollTop =
                elementOffsetTop -
                    (viewportHeight - elementHeight - endOffset - startOffset) / 2 +
                    startOffset;
            break;
        case 'end':
            nextScrollTop =
                elementOffsetTop + elementHeight - viewportHeight + endOffset;
            break;
    }
    return nextScrollTop;
}
/**
 * 匹配元素列表中第一个位于滚动盒子可视区域的元素
 *
 * @param {array} rects NodeRect 类型数组
 * @param {function} callback 匹配成功时调用，会接收匹配的元素的下标
 * @param {number} options.offset 偏移量
 * @param {number} options.errorValue 容错值
 */
export async function matchScrollVisible(rects, callback, options = {}) {
    const { offset: optionOffset = 0, errorValue = 3 } = options;
    const offset = optionOffset + errorValue;
    const convertedRect = rects.map((rect, i) => {
        return {
            top: rect.top,
            bottom: i < rects.length - 1 ? rects[i + 1].top : 0,
        };
    });
    for (let i = 0, l = convertedRect.length; i < l; i++) {
        const rect = convertedRect[i];
        if (i === 0 && rect.top > offset) {
            return callback(0);
        }
        if (rect.top <= offset && rect.bottom > offset) {
            return callback(i);
        }
        if (i === l - 1 && rect.bottom <= offset) {
            return callback(i);
        }
    }
}
/**
 * 保持纵横比缩放图片，只保证图片的短边能完全显示出来。也就是说，图片通常只在水平或垂直方向是完整的，另一个方向将会发生截取。
 */
export function getAspectFillSize(origWidth, origHeight, containerWidth, containerHeight) {
    let width = 0;
    let height = 0;
    if (origWidth > 0 && origHeight > 0) {
        if (origWidth / origHeight > containerWidth / containerHeight) {
            height = containerHeight;
            width = (origWidth / origHeight) * containerHeight;
        }
        else {
            width = containerWidth;
            height = (origHeight / origWidth) * containerWidth;
        }
    }
    return [width, height];
}
/**
 * 保持纵横比缩放图片，使图片的长边能完全显示出来。也就是说，可以完整地将图片显示出来。
 */
export function getAspectFitSize(origWidth, origHeight, containerWidth, containerHeight) {
    let width = 0;
    let height = 0;
    if (origWidth > 0 && origHeight > 0) {
        if (origWidth / origHeight > containerWidth / containerHeight) {
            width = containerWidth;
            height = (origHeight / origWidth) * containerWidth;
        }
        else {
            height = containerHeight;
            width = (origWidth / origHeight) * containerHeight;
        }
    }
    return [width, height];
}
/**
 * 获取两点间的距离
 */
export function getTwoPointsDistance(p1, p2) {
    return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
}
/**
 * @description: 根据原始坐标尺寸和缩放后的坐标尺寸算出转换的原点
 * @param {Rect} rect
 * @param {Rect} scaleRect
 * @return {[number, number]}
 */
export function getTransformOrigin(rect, scaleRect) {
    const ratio = scaleRect.width / rect.width;
    const originX = (rect.x + rect.width / 2 - scaleRect.x - scaleRect.width / 2) /
        (ratio - 1) +
        rect.width / 2;
    const originY = (rect.y + rect.height / 2 - scaleRect.y - scaleRect.height / 2) /
        (ratio - 1) +
        rect.height / 2;
    return [originX, originY];
}
